<script>
    import { afterUpdate, onDestroy, onMount } from "svelte";
    import elementResizeDetectorMaker from "element-resize-detector";
    import Monaco from "../utils/Monaco";
    import EditorTheme from "../utils/EditorTheme";
    import IndexedDBStore from "../utils/IndexedDBStore";

    const erd = elementResizeDetectorMaker();

    /** @type{HTMLDivElement} */
    let elementEditor = null;
    /** @type{import('monaco-editor').editor.IStandaloneCodeEditor} */
    let editor = null;

    export let guid = "editor-default";
    export let language = "javascript";
    export let editorOption = {};
    export let saveState = "true";
    export let content = "";
    export let updateData = (v) => {};

    onMount(async () => {
        console.log("onMount editor");

        let monaco = await Monaco.getMonaco();
        editor = monaco.editor.create(
            elementEditor,
            Object.assign(
                {
                    roundedSelection: true,
                    scrollBeyondLastLine: false,
                    readOnly: false,
                    wordWrap: "on",
                    renderWhitespace: true,
                    theme: "EditorTheme",
                    fontSize: 18,
                    dragAndDrop: true,
                    language: language,
                },
                editorOption
            )
        );

        editor.onDidChangeModelContent((e) => {
            let value = editor.getValue().trim();
            if (saveState) {
                IndexedDBStore.put(guid, value);
            }
            updateData(value);
        });

        for (const action of EditorTheme.Actions) {
            editor.addAction(action(monaco));
        }
        if (saveState == "true") {
            let value = (await IndexedDBStore.get(guid)) || "";
            editor.setValue(value);
        } else {
            editor.setValue(content);
        }
        erd.listenTo(elementEditor, () => {
            editor.layout();
        });
    });

    afterUpdate(async () => {
        if (!editor) return;
        let value = content;
        if (saveState == "true") {
            value = (await IndexedDBStore.get(guid)) || "";
        }
        editor.setValue(value);
    });

    onDestroy(() => {
        erd.removeAllListeners(elementEditor);
        if (editor) editor.dispose();
    });
</script>

<div bind:this={elementEditor} />

<style>
    div {
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
</style>
